package com.learn.exec;

/**
 * 生产者消费者问题
 *
 * 生产者将产品给店员，顾客从店员处取走商品。店员一次能持有最多20件商品。若超出，则提醒
 * 生产者等待，若无商品提醒消费者等待。
 *
 * 多线程、共享数据、线程安全、线程通信
 */
class Productor extends Thread{
    private Clerk c;

    public Productor(Clerk c){
        this.c = c;
    }

    @Override
    public void run() {
        System.out.println(getName()+ "：开始生产产品...");
        while (true){
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            c.product();
        }
    }
}

class Clerk{
    private static int MAX_GOODS = 0;

    public synchronized void product(){
        if (MAX_GOODS < 20){
            MAX_GOODS++;
            System.out.println(Thread.currentThread().getName() + "开始生产第" + MAX_GOODS +"件产品");
            notify();
        }else {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }

    public synchronized void consum(){

        if (MAX_GOODS > 0){
            try {
                Thread.sleep(50);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            System.out.println(Thread.currentThread().getName() + "开始消费第" + MAX_GOODS +"件产品");
            MAX_GOODS--;
            notify();
        }else {
            try {
                wait();
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
        }
    }
}

class  Consumer extends Thread{
    private Clerk c;

    public Consumer(Clerk c){
        this.c = c;
    }

    @Override
    public void run() {
        System.out.println(getName()+ "：开始消费产品...");
        while (true){
            try {
                Thread.sleep(10);
            } catch (InterruptedException e) {
                e.printStackTrace();
            }
            c.consum();
        }
    }
}

public class ProductAndConsum {
    public static void main(String[] args) {
        Clerk clerk = new Clerk();
        Productor productor = new Productor(clerk);
        Consumer consumer = new Consumer(clerk);

        productor.setName("productor");
        consumer.setName("consumer");

        productor.start();
        consumer.start();
    }
}
